<template>
  <div id="app">
    <canvas ref="gameCanvas"></canvas>
    <div class="game-ui">
      <div class="score">得分: {{ score }} (连击x{{ comboMultiplier }})</div>
      <div class="lives">剩余生命: {{ lives }}</div>
      <div v-if="gameOver" class="game-over">
        <h2>游戏结束!</h2>
        <button @click="restart">重新开始</button>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      canvas: null,
      ctx: null,
      player: {
        x: 375,
        y: 550,
        width: 50,
        height: 50,
        speed: 8
      },
      bullets: [],
      enemyBullets: [],
      enemies: [],
      powerUps: [],
      explosions: [],
      keys: {
        left: false,
        right: false,
        up: false,
        down: false
      },
      score: 0,
      lives: 3,
      gameOver: false,
      lastShot: 0,
      shotDelay: 200,
      comboMultiplier: 1,
      lastHitTime: 0,
      comboTimeout: 2000,
      bgOffset: 0,
      bgSpeed: 1,
      stars: [],
      lastEnemyShot: 0,
      enemyShotDelay: 1000
    }
  },
  mounted() {
    this.canvas = this.$refs.gameCanvas
    this.ctx = this.canvas.getContext('2d')
    this.canvas.width = 800
    this.canvas.height = 600
    
    // 初始化星空背景
    this.initStars()
    
    // 加载资源
    this.playerImg = new Image()
    this.playerImg.src = require('@/assets/player.png')
    
    this.bulletImg = new Image()
    this.bulletImg.src = require('@/assets/bullet.png')
    
    this.enemyBulletImg = new Image()
    this.enemyBulletImg.src = require('@/assets/enemy_bullet.png')
    
    this.enemyImgs = [
      new Image(), // 普通敌机
      new Image(), // 快速敌机
      new Image()  // BOSS
    ]
    this.enemyImgs[0].src = require('@/assets/enemy1.png')
    this.enemyImgs[1].src = require('@/assets/enemy2.png')
    this.enemyImgs[2].src = require('@/assets/enemy3.png')

    this.powerUpImg = new Image()
    this.powerUpImg.src = require('@/assets/powerup.png')

    this.explosionImgs = []
    for (let i = 1; i <= 5; i++) {
      const img = new Image()
      img.src = require(`@/assets/explosion${i}.png`)
      this.explosionImgs.push(img)
    }

    // 启动游戏
    this.gameLoop()
    setInterval(this.createEnemy, 1000)
    setInterval(this.createPowerUp, 5000)
    document.addEventListener('keydown', this.handleKeydown)
    document.addEventListener('keyup', this.handleKeyup)
  },
  methods: {
    initStars() {
      this.stars = []
      for (let i = 0; i < 100; i++) {
        this.stars.push({
          x: Math.random() * this.canvas.width,
          y: Math.random() * this.canvas.height,
          size: Math.random() * 2 + 1,
          speed: Math.random() * 2 + 0.5
        })
      }
    },
    drawBackground() {
      // 绘制星空背景
      this.ctx.fillStyle = '#000033'
      this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height)
      
      // 绘制星星
      this.ctx.fillStyle = 'white'
      this.stars.forEach(star => {
        star.y += star.speed
        if (star.y > this.canvas.height) {
          star.y = 0
          star.x = Math.random() * this.canvas.width
        }
        this.ctx.beginPath()
        this.ctx.arc(star.x, star.y, star.size, 0, Math.PI * 2)
        this.ctx.fill()
      })
      
      // 绘制渐变底部
      const gradient = this.ctx.createLinearGradient(0, this.canvas.height - 100, 0, this.canvas.height)
      gradient.addColorStop(0, 'rgba(0, 0, 64, 0)')
      gradient.addColorStop(1, 'rgba(0, 0, 128, 0.8)')
      this.ctx.fillStyle = gradient
      this.ctx.fillRect(0, this.canvas.height - 100, this.canvas.width, 100)
    },
    gameLoop() {
      if (this.gameOver) return
      
      // 绘制背景
      this.drawBackground()
      
      // 处理玩家移动
      this.handleMovement()
      
      // 绘制玩家
      this.ctx.drawImage(
        this.playerImg,
        this.player.x,
        this.player.y,
        this.player.width,
        this.player.height
      )
      
      // 更新子弹
      this.bullets.forEach((bullet, index) => {
        bullet.y -= 10
        this.ctx.drawImage(this.bulletImg, bullet.x, bullet.y, 10, 20)
        
        if (bullet.y < 0) this.bullets.splice(index, 1)
      })
      
      // 更新敌机子弹
      this.enemyBullets.forEach((bullet, index) => {
        bullet.y += 5
        this.ctx.drawImage(this.enemyBulletImg, bullet.x, bullet.y, 10, 20)
        
        // 检测玩家被击中
        if (this.checkPlayerHit(bullet)) {
          this.lives--
          this.enemyBullets.splice(index, 1)
          if (this.lives <= 0) this.gameOver = true
        }
        
        if (bullet.y > this.canvas.height) this.enemyBullets.splice(index, 1)
      })
      
      // 更新敌机
      this.enemies.forEach((enemy, index) => {
        enemy.y += enemy.speed
        
        // BOSS敌机特殊行为
        if (enemy.type === 2) {
          // 左右移动
          enemy.x += enemy.moveDirection * 2
          if (enemy.x <= 0 || enemy.x + enemy.width >= this.canvas.width) {
            enemy.moveDirection *= -1
          }
          
          // 发射子弹
          if (Date.now() - this.lastEnemyShot > this.enemyShotDelay) {
            this.enemyBullets.push({
              x: enemy.x + enemy.width/2 - 5,
              y: enemy.y + enemy.height,
              width: 10,
              height: 20
            })
            this.lastEnemyShot = Date.now()
          }
        }
        
        this.ctx.drawImage(
          this.enemyImgs[enemy.type],
          enemy.x,
          enemy.y,
          enemy.width,
          enemy.height
        )
        
        // 碰撞检测
        if (this.checkCollision(enemy)) {
          this.lives -= enemy.damage
          this.createExplosion(enemy.x, enemy.y, enemy.width, enemy.height)
          this.enemies.splice(index, 1)
          if (this.lives <= 0) this.gameOver = true
        }
        
        // 子弹命中检测
        this.bullets.forEach((bullet, bIndex) => {
          if (this.checkBulletHit(bullet, enemy)) {
            this.score += 100 * this.comboMultiplier
            this.updateCombo()
            this.createExplosion(enemy.x, enemy.y, enemy.width, enemy.height)
            this.enemies.splice(index, 1)
            this.bullets.splice(bIndex, 1)
          }
        })
      })
      
      // 更新道具
      this.powerUps.forEach((powerUp, index) => {
        powerUp.y += 2
        this.ctx.drawImage(
          this.powerUpImg,
          powerUp.x,
          powerUp.y,
          30,
          30
        )
        
        if (this.checkPowerUpCollision(powerUp)) {
          this.applyPowerUp(powerUp.type)
          this.powerUps.splice(index, 1)
        }
      })
      
      // 更新爆炸效果
      this.explosions.forEach((explosion, index) => {
        explosion.frame++
        if (explosion.frame >= this.explosionImgs.length * 3) {
          this.explosions.splice(index, 1)
        } else {
          const imgIndex = Math.floor(explosion.frame / 3)
          this.ctx.drawImage(
            this.explosionImgs[imgIndex],
            explosion.x,
            explosion.y,
            explosion.width,
            explosion.height
          )
        }
      })
      
      requestAnimationFrame(this.gameLoop)
    },
    createExplosion(x, y, width, height) {
      this.explosions.push({
        x: x - width/2,
        y: y - height/2,
        width: width * 2,
        height: height * 2,
        frame: 0
      })
    },
    handleMovement() {
      // 处理键盘输入
      if (this.keys.left) this.player.x -= this.player.speed
      if (this.keys.right) this.player.x += this.player.speed
      if (this.keys.up) this.player.y -= this.player.speed
      if (this.keys.down) this.player.y += this.player.speed
      
      // 边界检测
      this.player.x = Math.max(0, Math.min(this.canvas.width - this.player.width, this.player.x))
      this.player.y = Math.max(0, Math.min(this.canvas.height - this.player.height, this.player.y))
    },
    handleKeydown(e) {
      switch(e.code) {
        case 'Space':
          if (Date.now() - this.lastShot > this.shotDelay) {
            this.bullets.push({
              x: this.player.x + this.player.width/2 - 5,
              y: this.player.y,
              width: 10,
              height: 20
            })
            this.lastShot = Date.now()
          }
          break
        case 'ArrowLeft': this.keys.left = true; break
        case 'ArrowRight': this.keys.right = true; break
        case 'ArrowUp': this.keys.up = true; break
        case 'ArrowDown': this.keys.down = true; break
      }
    },
    handleKeyup(e) {
      switch(e.code) {
        case 'ArrowLeft': this.keys.left = false; break
        case 'ArrowRight': this.keys.right = false; break
        case 'ArrowUp': this.keys.up = false; break
        case 'ArrowDown': this.keys.down = false; break
      }
    },
    createEnemy() {
      const type = Math.random() < 0.1 ? 2 : Math.random() < 0.3 ? 1 : 0
      const speeds = [2, 5, 1]
      const sizes = [40, 30, 80]
      const enemy = {
        type,
        x: Math.random() * (this.canvas.width - sizes[type]),
        y: -sizes[type],
        width: sizes[type],
        height: sizes[type],
        speed: speeds[type],
        damage: type === 2 ? 2 : 1
      }
      
      // 为BOSS敌机添加移动方向
      if (type === 2) {
        enemy.moveDirection = Math.random() < 0.5 ? -1 : 1
      }
      
      this.enemies.push(enemy)
    },
    createPowerUp() {
      if (Math.random() < 0.3) {
        this.powerUps.push({
          x: Math.random() * (this.canvas.width - 30),
          y: -30,
          width: 30,
          height: 30,
          type: Math.floor(Math.random() * 3) // 0: 生命 1: 连击 2: 速射
        })
      }
    },
    checkCollision(enemy) {
      return (
        this.player.x < enemy.x + enemy.width &&
        this.player.x + this.player.width > enemy.x &&
        this.player.y < enemy.y + enemy.height &&
        this.player.y + this.player.height > enemy.y
      )
    },
    checkPlayerHit(bullet) {
      return (
        this.player.x < bullet.x + bullet.width &&
        this.player.x + this.player.width > bullet.x &&
        this.player.y < bullet.y + bullet.height &&
        this.player.y + this.player.height > bullet.y
      )
    },
    checkBulletHit(bullet, enemy) {
      return (
        bullet.x < enemy.x + enemy.width &&
        bullet.x + bullet.width > enemy.x &&
        bullet.y < enemy.y + enemy.height &&
        bullet.y + bullet.height > enemy.y
      )
    },
    checkPowerUpCollision(powerUp) {
      return (
        this.player.x < powerUp.x + powerUp.width &&
        this.player.x + this.player.width > powerUp.x &&
        this.player.y < powerUp.y + powerUp.height &&
        this.player.y + this.player.height > powerUp.y
      )
    },
    applyPowerUp(type) {
      switch(type) {
        case 0: // 生命
          this.lives = Math.min(5, this.lives + 1)
          break
        case 1: // 连击
          this.comboMultiplier = 3
          setTimeout(() => this.comboMultiplier = 1, 5000)
          break
        case 2: // 速射
          this.shotDelay = 100
          setTimeout(() => this.shotDelay = 200, 5000)
          break
      }
    },
    updateCombo() {
      if (Date.now() - this.lastHitTime < this.comboTimeout) {
        this.comboMultiplier = Math.min(5, this.comboMultiplier + 0.2)
      } else {
        this.comboMultiplier = 1
      }
      this.lastHitTime = Date.now()
    },
    restart() {
      this.bullets = []
      this.enemyBullets = []
      this.enemies = []
      this.powerUps = []
      this.explosions = []
      this.score = 0
      this.lives = 3
      this.gameOver = false
      this.comboMultiplier = 1
      this.player.x = 375
      this.player.y = 550
      this.gameLoop()
    }
  },
  beforeDestroy() {
    document.removeEventListener('keydown', this.handleKeydown)
    document.removeEventListener('keyup', this.handleKeyup)
  }
}
</script>

<style>
#app {
  position: relative;
  width: 800px;
  height: 600px;
  margin: 0 auto;
  overflow: hidden;
}

canvas {
  display: block;
  background-color: #000;
}

.game-ui {
  position: absolute;
  top: 10px;
  left: 10px;
  color: white;
  font-family: Arial, sans-serif;
  font-size: 18px;
  text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.7);
}

.score, .lives {
  margin-bottom: 10px;
}

.game-over {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: rgba(0, 0, 0, 0.8);
  padding: 20px;
  border-radius: 10px;
  text-align: center;
  color: white;
}

.game-over h2 {
  margin-top: 0;
  color: #ff5555;
}

.game-over button {
  background-color: #4CAF50;
  border: none;
  color: white;
  padding: 10px 20px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  margin: 10px 2px;
  cursor: pointer;
  border-radius: 5px;
  transition: background-color 0.3s;
}

.game-over button:hover {
  background-color: #45a049;
}
</style>